<html>
<head><meta charset="utf-8"><title>slice-of-ZST validity · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html">slice-of-ZST validity</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="185228222"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185228222" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185228222">(Jan 09 2020 at 16:24)</a>:</h4>
<p>The bitvec crate does some weird things so that the BitSlice type can work. Specifically, <code>&amp;BitSlice&lt;...&gt;</code> ends up being (transparent wrapper around a) <code>&amp;[()]</code>, except both the length and pointer parts store specially encoded values (See BitPtr in <a href="https://github.com/myrrlyn/bitvec/blob/master/src/pointer.rs" target="_blank" title="https://github.com/myrrlyn/bitvec/blob/master/src/pointer.rs">https://github.com/myrrlyn/bitvec/blob/master/src/pointer.rs</a> for how it's encoded, but the type in question is BitSlice in <a href="https://github.com/myrrlyn/bitvec/blob/master/src/slice.rs" target="_blank" title="https://github.com/myrrlyn/bitvec/blob/master/src/slice.rs">https://github.com/myrrlyn/bitvec/blob/master/src/slice.rs</a>).</p>
<p>I would have thought this was unsound, but I can't actually think of a reason why. It's still nonnull, it respects alignment requirements (since <code>()</code> is 1-byte aligned), and since it's a ZST, the reference wouldn't be dereferencable to LLVM (and IDK if that attribute even gets applied to slice pointers).</p>
<p>So... I <em>think</em> this boils down to: "does &amp;[()] have validity requirements beyond 'the pointer part can't be null'?".</p>



<a name="185232262"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185232262" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185232262">(Jan 09 2020 at 17:00)</a>:</h4>
<p>Currently <code>std::mem::size_of::&lt;&amp;[()]&gt;()</code> returns 16 on x86_64</p>



<a name="185232291"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185232291" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185232291">(Jan 09 2020 at 17:00)</a>:</h4>
<p>AFAICT we can optimize that to <code>8</code></p>



<a name="185232320"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185232320" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185232320">(Jan 09 2020 at 17:01)</a>:</h4>
<p>(e.g. make <code>&amp;[ZST]</code> store a <code>usize</code> only)</p>



<a name="185232496"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185232496" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185232496">(Jan 09 2020 at 17:02)</a>:</h4>
<p>Right now  the proposed layout for fat pointers in the UCGs does not allow that</p>



<a name="185232534"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185232534" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185232534">(Jan 09 2020 at 17:02)</a>:</h4>
<p>But right now the layout of <code>&amp;T</code> is unspecified, so we could still change that</p>



<a name="185232564"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185232564" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185232564">(Jan 09 2020 at 17:03)</a>:</h4>
<p>The validity of <code>&amp;[T]</code> is also not written down anywhere yet</p>



<a name="185232598"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185232598" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185232598">(Jan 09 2020 at 17:03)</a>:</h4>
<p>The pointer needs to be nonnull, aligned, and dereferenceable</p>



<a name="185232626"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185232626" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185232626">(Jan 09 2020 at 17:03)</a>:</h4>
<p>but for <code>&amp;[()]</code> all pointers except for <code>ptr::null()</code> satisfy that</p>



<a name="185232762"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185232762" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185232762">(Jan 09 2020 at 17:04)</a>:</h4>
<p>since the alignment of <code>()</code> is <code>1</code>, and the slice occupies 0 bytes independently of its size, so the requirement is essentially <code>dereferenceable(0)</code>, which as long as the pointer is not null, is a condition that's satisfied</p>



<a name="185233091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185233091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185233091">(Jan 09 2020 at 17:07)</a>:</h4>
<p>I've opened <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/224" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/224">ucg#224</a> to track the optimization</p>



<a name="185691250"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185691250" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185691250">(Jan 15 2020 at 12:06)</a>:</h4>
<blockquote>
<p>but for <code>&amp;[()]</code> all pointers except for <code>ptr::null()</code> satisfy that</p>
</blockquote>
<p>I almost agree... one class of pointers that might not satisfy this is "dangling pointers LLVM knows" -- as in, dangling pointers into or derived from LLVM-controlled allocations. LLVM's spec is not clear enough to tell whether that is legal or not, and my attempt at asking them didnt work out (I think they failed to entirely understand where I was coming from -- it's a subtle question, and I have a hard time phrasing it well)</p>



<a name="185691284"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185691284" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185691284">(Jan 15 2020 at 12:07)</a>:</h4>
<p>so, I wouldnt subscribe to the following code being allowed:</p>
<div class="codehilite"><pre><span></span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="kt">i32</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">ptr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">x</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="p">();</span><span class="w"></span>
<span class="n">drop</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">zst_slice</span>: <span class="kp">&amp;</span><span class="p">[()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">slice</span>::<span class="n">from_raw_parts</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span><span class="w"> </span><span class="mi">1024</span><span class="p">);</span><span class="w"></span>
</pre></div>



<a name="185691344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185691344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185691344">(Jan 15 2020 at 12:08)</a>:</h4>
<p>LLVM might be or become "smart enough" to deduce that this pointer cannot possibly be dereferencable</p>



<a name="185696389"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185696389" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185696389">(Jan 15 2020 at 13:21)</a>:</h4>
<p>hmm</p>



<a name="185696398"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185696398" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185696398">(Jan 15 2020 at 13:21)</a>:</h4>
<p>isn't this already the case ?</p>



<a name="185696411"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185696411" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185696411">(Jan 15 2020 at 13:21)</a>:</h4>
<p>That last pointer is "dereferenceable for 0 bytes"</p>



<a name="185696484"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185696484" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185696484">(Jan 15 2020 at 13:22)</a>:</h4>
<p>The trouble is that the lifetime of the allocation the pointer was derived from has ended</p>



<a name="185696516"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185696516" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185696516">(Jan 15 2020 at 13:23)</a>:</h4>
<p>Do we generate ptr reads/writes of zero-size in LLVM-Ir for pointers to ZSTs ?</p>



<a name="185696733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185696733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185696733">(Jan 15 2020 at 13:26)</a>:</h4>
<p>(no we don't)</p>



<a name="185714073"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185714073" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185714073">(Jan 15 2020 at 16:21)</a>:</h4>
<blockquote>
<p>That last pointer is "dereferenceable for 0 bytes"</p>
</blockquote>
<p>you mean <code>zst_slice</code> in my example? I'd say it is <em>not</em> dereferencable for 0 bytes. At least not until we get explicit confirmation from LLVM that it is.</p>



<a name="185714194"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST%20validity/near/185714194" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/slice-of-ZST.20validity.html#185714194">(Jan 15 2020 at 16:22)</a>:</h4>
<p>I would not be surprised at all if some LLVM dev went "after <code>free</code>ing an allocation, no ptr derived from that allocation can be dereferencable, and hence I can do X"</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>